<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container :disabled="formDisabled">
      <!-- 主表单区域 -->
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <a-row>
          <a-col :span="8">
            <a-form-model-item label="单据编号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="billNo">
              <a-input v-model="model.billNo" placeholder="请输入单据编号" disabled></a-input>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="单据日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="billDate">
              <j-date placeholder="请选择单据日期" v-model="model.billDate" style="width: 100%"/>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="库房" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="warehouseId">
              <j-search-select-tag ref="warehouseSearch" v-model="model.warehouseId" dict="mdm_warehouse,warehouse_name,id"/>
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="供应商" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="supplyId">
              <j-search-select-tag v-model="model.supplyId" dict="mdm_supply,supply_full_name,id"/>
            </a-form-model-item>
          </a-col>
          <a-col :span="8" >
            <a-form-model-item label="项目" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="projectId_dictText">
              <j-popup
                v-model="model.projectId_dictText"
                field="projectId"
                org-fields="id,project_name"
                dest-fields="projectId,projectId_dictText"
                code="quote_project_popup"
                :multi="false"
                @input="projectPopupCallback"
              />
            </a-form-model-item>
          </a-col>
          <a-col :span="16">
            <a-form-model-item label="备注" :labelCol="labelCol2" :wrapperCol="wrapperCol2" prop="remark">
              <a-textarea v-model="model.remark" rows="2" placeholder="请输入备注"/>
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
    <!-- 子表单区域 -->
    <a-tabs v-model="activeKey" @change="handleChangeTabs">
      <a-tab-pane tab="单据明细" :key="refKeys[0]" :forceRender="true">
        <j-editable-table
          :ref="refKeys[0]"
          :loading="mmStockInOutDetailTable.loading"
          :columns="mmStockInOutDetailTable.columns"
          :dataSource="mmStockInOutDetailTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="true"
          :actionButton="true"
          :actionAddButton="false"
          @added="detailAdded"
          @valueChange="qtyAndPriceChange">
          <div slot="buttonBefore">
            <div class="action-button">
              <a-button type="primary" icon="plus" @click="chooseMaterialStock" :disabled="formDisabled">新增</a-button>
              <span class="gap"></span>
            </div>
          </div>
        </j-editable-table>
        <j-popup-onl-report ref="jPopupOnlReport" code="mm_material_stock_pop" multi="true" :param="materialStockParam"
                            @ok="stockPopupCallback"/>
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>

<script>

import {getAction} from '@/api/manage'
import {FormTypes, getRefPromise, VALIDATE_NO_PASSED} from '@/utils/JEditableTableUtil'
import {JEditableTableModelMixin} from '@/mixins/JEditableTableModelMixin'
import moment from "moment";
import Vue from 'vue'

export default {
  name: 'MmPurchaseInForm',
  mixins: [JEditableTableModelMixin],
  components: {},
  data() {
    return {
      labelCol: {
        xs: {span: 24},
        sm: {span: 6},
      },
      wrapperCol: {
        xs: {span: 24},
        sm: {span: 16},
      },
      labelCol2: {
        xs: {span: 24},
        sm: {span: 3},
      },
      wrapperCol2: {
        xs: {span: 24},
        sm: {span: 20},
      },
      model: {
        billDate: moment(new Date()).format('YYYY-MM-DD')
      },
      warehouseUpdateCancel: false,
      materialStockParam: {},
      // 新增时子表默认添加几行空数据
      addDefaultRowNum: 1,
      validatorRules: {
        warehouseId: [
          {required: true, message: '请输入库房!'}
        ],
        billDate: [
          {required: true, message: '请输入单据日期!'}
        ],
        supplyId: [
          {required: true, message: '请输入供应商!'}
        ]
      },
      refKeys: ['mmStockInOutDetail',],
      tableKeys: ['mmStockInOutDetail',],
      activeKey: 'mmStockInOutDetail',
      // 库存单据明细
      mmStockInOutDetailTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '物料描述',
            key: 'materialDesc',
            type: FormTypes.popup,
            popupCode: "mm_material_stock_pop",
            orgFields: 'id,material_id,material_no,material_desc,unit,stock_qty_available,batch_no,unit_price,available_sum_price,warehouse_id,storage_location_id,max_stock_qty_available,project_id',
            destFields: 'materialStockId,materialId,materialNo,materialDesc,unit,qty,batchNo,unitPrice,sumPrice,warehouseId,storageLocationId,maxStockQtyAvailable,projectId',
            width: "260px",
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{required: true, message: '${title}不能为空'}],
          },
          {
            title: '单位',
            key: 'unit',
            type: FormTypes.sel_search,
            dictCode: "mdm_unit,unit_name,unit_code",
            width: "110px",
            placeholder: '请输入${title}',
            defaultValue: '',
            disabled: true
          },
          {
            title: '数量',
            key: 'qty',
            type: FormTypes.inputNumber,
            width: "140px",
            placeholder: '请输入${title}',
            defaultValue: '0',
            statistics: true,
            scale: 2,
            validateRules: [
              {required: true, message: '${title}不能为空'},
              {pattern: /^(?!(0[0-9]{0,}$))[0-9]{1,}[.]{0,}[0-9]{0,}$/, message: '请输入大于零的数'},
              {
                handler(type, value, row, column, callback, target) {
                  let {values} = target.getValuesSync({validate: false, rowIds: [row.id]});
                  if (type === 'blur' || type === 'getValues') {
                    if (value > values[0].maxStockQtyAvailable) {
                      callback(false, '${title}不能超出可用库存量：' + values[0].maxStockQtyAvailable)
                      return
                    } else {
                      callback(true)
                    }
                  } else {
                    callback();
                  }
                }
              },
            ],
          },
          {
            title: '含税单价',
            key: 'unitPrice',
            type: FormTypes.inputNumber,
            width: "140px",
            placeholder: '请输入${title}',
            defaultValue: '0',
          },
          {
            title: '含税金额',
            key: 'sumPrice',
            type: FormTypes.inputNumber,
            width: "140px",
            placeholder: '请输入${title}',
            defaultValue: '0',
            statistics: true,
            scale: 2,
          },
          {
            title: '项目',
            key: 'projectId',
            type: FormTypes.sel_search,
            dictCode: "quote_project,project_name,id",
            width: "140px",
            placeholder: '请输入${title}',
            defaultValue: '',
            disabled: true
          },
          {
            title: '批次',
            key: 'batchNo',
            type: FormTypes.input,
            width: "160px",
            placeholder: '请输入${title}',
            defaultValue: '',
            disabled: true
          },
          {
            title: '库位',
            key: 'storageLocationId',
            type: FormTypes.sel_search,
            dictCode: "mdm_storage_location,location_no,id",
            width: "160px",
            placeholder: '请输入${title}',
            defaultValue: '',
            disabled: true
          },
          {
            title: '备注',
            key: 'remark',
            type: FormTypes.input,
            width: "240px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '行号',
            key: 'lineNo',
            type: FormTypes.inputNumber,
            width: "70px",
            placeholder: '请输入${title}',
            defaultValue: '',
            disabled: true,
          },
          {
            title: 'materialId',
            key: 'materialId',
            type: "hidden"
          },
          {
            title: 'materialNo',
            key: 'materialNo',
            type: "hidden"
          },
          {
            title: '库房',
            key: 'warehouseId',
            type: 'hidden',
          },
          {
            title: '最大可用库存量',
            key: 'maxStockQtyAvailable',
            type: 'hidden',
            defaultValue: 0
          },
          {
            title: '库存主键',
            key: 'materialStockId',
            type: 'hidden',
          },
        ]
      },
      url: {
        add: "/mm/stockInOut/addPurchaseBack",
        edit: "/mm/stockInOut/edit",
        queryById: "/mm/stockInOut/queryById",
        genCode: "/mdm/codeRule/genStockInOutCode",
        mmStockInOutDetail: {
          list: '/mm/stockInOut/queryMmStockInOutDetailByMainId'
        },
      }
    }
  },
  props: {
    //表单禁用
    disabled: {
      type: Boolean,
      default: false,
      required: false
    }
  },
  computed: {
    formDisabled() {
      return this.disabled
    },
  },
  watch: {
    'model.warehouseId': {
      deep: true,
      handler(newVal, oldVal) {
        if(this.warehouseUpdateCancel){
          this.warehouseUpdateCancel = false;
          return;
        }
        let {values} = this.$refs[this.refKeys[0]].getValuesAsync({validate: false})
        let hasDetail = values.some((val)=>{
          return val.warehouseId && val.warehouseId !== newVal
        })
        if (hasDetail) {
          this.$message.error("已有退货明细，不能修改库房!")
          this.warehouseUpdateCancel = true;
          this.$refs['warehouseSearch'].handleChange(oldVal);
          return;
        }
      }
    }
  },
  created() {
  },
  methods: {
    addBefore() {
      this.genBillNo();
      this.mmStockInOutDetailTable.dataSource = []
    },
    genBillNo() {
      this.confirmLoading = true;
      getAction(this.url.genCode, {}).then(res => {
        if (res.success) {
          this.model.billNo = res.result;
        }
      }).finally(() => {
        this.confirmLoading = false;
      })
    },
    getAllTable() {
      let values = this.tableKeys.map(key => getRefPromise(this, key))
      return Promise.all(values)
    },
    /** 调用完edit()方法之后会自动调用此方法 */
    editAfter() {
      this.$nextTick(() => {
      })
      // 加载子表数据
      if (this.model.id) {
        let params = {id: this.model.pid}
        this.requestSubTableData(this.url.mmStockInOutDetail.list, params, this.mmStockInOutDetailTable)
      }
    },
    //校验所有一对一子表表单
    validateSubForm(allValues) {
      return new Promise((resolve, reject) => {
        Promise.all([]).then(() => {
          resolve(allValues)
        }).catch(e => {
          if (e.error === VALIDATE_NO_PASSED) {
            // 如果有未通过表单验证的子表，就自动跳转到它所在的tab
            this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
          } else {
            console.error(e)
          }
        })
      })
    },
    /** 整理成formData */
    classifyIntoFormData(allValues) {
      let main = Object.assign(this.model, allValues.formValue)
      return {
        ...main, // 展开
        mmStockInOutDetailList: allValues.tablesValue[0].values,
      }
    },
    validateError(msg) {
      this.$message.error(msg)
    },
    qtyAndPriceChange(parm) {
      if (parm && parm['column'] && parm['row'] && parm['target']) {
        let cols = ['qty', 'sumPrice', 'unitPrice'];
        let key = parm.column.key;
        if (cols.includes(key)) {
          let editableTable = parm['target'];
          // 重新计算当前行总金额
          if (key === cols[0] || key === cols[2]) {
            let unitPrice = parm.row[cols[2]] || 0;
            let qty = parm.row[cols[0]] || 0;
            let sumPrice = Math.round(unitPrice * qty * 100) / 100;
            editableTable.setValues([{rowKey: parm.row.id, values: {[cols[1]]: sumPrice}}]);
          }
          // 重新计算单价
          if (key === cols[1]) {
            let sumPrice = parm.row[cols[1]] || 0;
            let qty = parm.row[cols[0]] || 0;
            if (qty != 0) {
              let unitPrice = Math.round(sumPrice / qty * 100) / 100;
              editableTable.setValues([{rowKey: parm.row.id, values: {[cols[2]]: unitPrice}}]);
            }
          }
          // 重新计算统计列
          editableTable.recalcOneStatisticsColumn(cols[0]);
          editableTable.recalcOneStatisticsColumn(cols[1]);
        }
      }
    },
    detailAdded: function (obj) {
      let editTable = this.$refs[this.refKeys[0]];
      let lineNo = this.generateLineNo();
      editTable.setValues([{rowKey: obj.row.id, values: {lineNo: lineNo}}])
    },
    /** 生成行号 */
    generateLineNo() {
      let editTable = this.$refs[this.refKeys[0]];
      let rows = editTable.rows;
      let num = 10;
      if (rows.length > 1) {
        let lastId = editTable.getCleanId(rows[rows.length - 2].id)
        let {values} = editTable.getValuesSync({validate: false, rowIds: [lastId]});
        num = Number(values[0].lineNo) + 10
      }
      return num
    },
    chooseMaterialStock() {
      if (!this.model.warehouseId) {
        this.$message.error("请先选择库房！")
        return
      }
      let materialStockIds = this.getMaterialStockIdsChoosed();
      this.materialStockParam = {warehouseId: this.model.warehouseId, projectId: this.model.projectId, ids: materialStockIds}
      this.$refs.jPopupOnlReport.show();
    },
    getMaterialStockIdsChoosed(){
      let editTable = this.$refs[this.refKeys[0]];
      let {values} = editTable.getValuesSync({validate: false});
      let ids = "";
      if(values.length > 0){
        for(let materialStock of values){
          ids = ids + (ids ? ',' : '') + materialStock.materialStockId;
        }
      }
      return ids;
    },
    stockPopupCallback(rows) {
      if (rows && rows.length > 0) {
        let mmStockInOutDetailTable = this.$refs[this.refKeys[0]];
        let oldData = mmStockInOutDetailTable.getValuesSync();
        let column = this.mmStockInOutDetailTable.columns.find(col => col.key === 'materialDesc')
        let orgFieldsArr = ['id','material_id','material_no','material_desc','unit','stock_qty_available','batch_no','unit_price','available_sum_price','warehouse_id','storage_location_id','max_stock_qty_available','project_id'];
        let destFieldsArr = ['materialStockId','materialId','materialNo','materialDesc','unit','qty','batchNo','unitPrice','sumPrice','warehouseId','storageLocationId','maxStockQtyAvailable','projectId'];
        let addRow, addData
        for (let i = 0; i < rows.length; i++) {
          if (!(i === 0 && oldData && oldData.values && oldData.values.length === 1 && !oldData.values[0].materialDesc)) {
            mmStockInOutDetailTable.add();
          }
          addRow = mmStockInOutDetailTable.rows[mmStockInOutDetailTable.rows.length - 1];
          // key转换
          for (let j = 0; j < orgFieldsArr.length; j++) {
            rows[i][destFieldsArr[j]] = rows[i][orgFieldsArr[j]];
            if (destFieldsArr[j] !== orgFieldsArr[j]) {
              delete rows[i][orgFieldsArr[j]]
            }
          }
          addData = Object.assign({}, rows[i])
          mmStockInOutDetailTable.popupCallback(addData.materialDesc, addData, 'materialDesc' + addRow.id, addRow, column)
        }
      }
    },
    handleValidOk(){
      let editTable = this.$refs[this.refKeys[0]];
      let rows = editTable.rows
      if(rows.length === 0){
        this.$message.warning("请输入明细！");
      }else{
        this.handleOk();
      }
    },
    projectPopupCallback(value,row){
      this.model = Object.assign(this.model, row);
    },
  }
}
</script>

<style scoped>
.action-button {
  margin-bottom: 8px;
}

.gap {
  padding-left: 8px;
}
</style>